﻿
/// <reference path="Container.js" />
/// <reference path="_namespace.js" />

/*****************************************************************************
Ajax library class definition. Kevin Robinson 2006.
Class: ajax.components.Splitter
/*****************************************************************************/


ajax.lang.addNamespace("ajax.components");

//-----------------------------------------------------------------------------
ajax.components.Splitter = function(doc, parentNode, layerName, w, h, splitterType)
{
    ajax.components.Splitter.superConstructor.apply(this, arguments);
   
    // we must load now...    
    this.splitterTypes              = ajax.lang.safeCall("ajax.components.Splitter", "getSplitterTypes");
    this.splitterType               = splitterType; 
    this.splitterBars               = [];
    this.frames                     = [];  // holds container objects
    
    // Style
    this.layerStyle.overflow        = "hidden";
    this.splitterBarStyle = 
    {        
    }
    
    // support barMoved event
    this.getEvent(this.window, "onBarMoved");
}

//-----------------------------------------------------------------------------
ajax.lang.extend("ajax.components.Splitter", "ajax.components.Container"); // Inherit
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
ajax.components.Splitter.prototype.setSize = function(width, height)
{
    // Call super
    ajax.components.Splitter.superClass.setSize.call(this, width, height);
    
    // call the move handler for each splitterBar so they know about our new dimensions
    for (var i = 0; i < this.splitterBars.length; i++)
    {
        var bar = this.splitterBars[i];
        var e   = {index: i, x: bar.x, y: bar.y};
        this.onSplitterMoveHandler(e);
    }
}


ajax.components.Splitter.prototype.onSplitterMoveHandler = function(e)
{
    // Grab the splitterBar, the Adjacent frames and adjacent bars
    var bar     = this.splitterBars[e.index];            
    var frameL  = this.frames[e.index];
    var frameR  = this.frames[e.index + 1];
    var barL    = this.splitterBars[e.index - 1];
    var barR    = this.splitterBars[e.index + 1];
    
    switch (this.splitterType)
    {
        case this.splitterTypes.Vertical:
        {
            // Size adj frames -------------------------------------------------------------
            if (frameL)
            {
                if (barL)
                    frameL.setSize( bar.x - barL.x - barL.width, frameL.height);
                else
                    frameL.setSize(bar.x, frameL.height);
            }
            if (frameR)
            {
                if (barR)
                    frameR.setSize( barR.x - bar.x - bar.width, frameR.height);
                else
                    frameR.setSize( this.width - bar.x - bar.width, frameR.height);
                    
                frameR.setPosition(bar.x + bar.width, frameR.y);
            }
            
            // update the adjacent splitter Bars (if any) and set their constraints----------
            if (barL)
                barL.dragController.maxX = bar.x - barL.width;
            if (barR)
                barR.dragController.minX = bar.x + bar.width;
                
            // now set our constraints ------------------------------------------------------
            if (barL)
                bar.dragController.minX = barL.x + barL.width;
            else
                bar.dragController.minX = 0;
            
            if (barR)
                bar.dragController.maxX = barR.x - bar.width;
            else
                bar.dragController.maxX = this.width - bar.width;
        
            break;       
        }
            
        case this.splitterTypes.Horizontal:
        {            
            // Size adj frames -------------------------------------------------------------
            if (frameL)
            {
                if (barL)
                    frameL.setSize( frameL.width, bar.y - barL.y - bar.x - barL.height);
                else
                    frameL.setSize(frameL.width, bar.y);
            }
            if (frameR)
            {
                if (barR)
                    frameR.setSize( frameR.width, barR.y - bar.y - bar.height);
                else
                    frameR.setSize( frameR.width, this.height - bar.y - bar.height);                        
                    
                frameR.setPosition(frameR.x, bar.y + bar.height);
                
            }
            
            // update the adjacent splitter Bars (if any) and set their constraints----------
            if (barL)
                barL.dragController.maxY = bar.y - barL.height;
            if (barR)
                barR.dragController.minY = bar.y + bar.height;
                
            // now set our constraints ------------------------------------------------------
            if (barL)
                bar.dragController.minY = barL.y + barL.height;
            else
                bar.dragController.minY = 0;
            
            if (barR)
                bar.dragController.maxY = barR.y - bar.height;
            else
                bar.dragController.maxY = this.height - bar.height;
            break;            
        }
            
        default:
            break;
    }
    
    this.onBarMoved.call(this);
}

//-----------------------------------------------------------------------------
ajax.components.Splitter.prototype.addFrame = function(frame)
{          
    var self = this;
    
    if (this.frames.length >= this.numSplits+1)
    {
        ajax.debug.Output.writeLn(this + ": Frames exceed limit so ignoring");
        return;
    }
    
    // Add them to our array if they are not there already
    if (!this.frames.contains(frame))    
        this.frames.append(frame, true);
        
    // Make sure we and the frame are loaded.
    if (!this.layer)
        this.load();
    frame.parentNode = this.layer;
    frame.show(0, 0); // init position
    
    // The frame MUST be using Absolute positioning...and pixel sizing
    frame.layer.style.position = "absolute";
    frame.units.size.width = frame.units.size.height = frame.units.position.x = frame.units.position.y;
    
    
    // With that in place - have it so that resize events from this control affect the frame    
    switch (this.splitterType)
    {
        case this.splitterTypes.Vertical:
        {
            // The height needs to be set to the same as our height, keeping width as it was.
            frame.setSize(frame.width, this.height);
            this.getEvent(this.window, "onResize").addListener(function(e)
                {
                    frame.setSize(frame.width, this.height);
                }
            );                        
            break;
        }
        case this.splitterTypes.Horizontal:
        {
            // The width needs to be set to the same as our width, keeping height as it was
            frame.setSize(this.width, frame.height);
            this.getEvent(this.window, "onResize").addListener(function(e)
                {
                    frame.setSize(this.width, frame.height);
                }
            );
            break;
        }            
        default:
            break;
    }
    
    
    // Add the frame 
    this.layer.appendChild(frame.layer);
    
    // if frames.length > 1 then add a splitter bar
    if (this.frames.length > 1)
    {
        var newSplitter = ajax.lang.safeNew("ajax.components.SplitterBar", 
                                            this.doc, this.layer, 
                                            this.layerName != "" ? this.layerName + "_SplitterBar" : "", 
                                            this.splitterType);
        newSplitter.show();
        this.copyProperties(newSplitter.layer.style, this.splitterBarStyle);
        
        // When the splitter bar has moved we wrap the event args and pass to our
        // method that will resize everything, and raise our onBarMoved event
        newSplitter.getEvent(this.window, "onMove").addListener(function(e)
            {
                // Add the index to the event args and pass through
                e.index = this.index;
                self.onSplitterMoveHandler(e);
            }
        );
        
        // when the user starts dragging a splitterBar, ensure the splitterBar is on top
        newSplitter.dragController.getEvent(this.window, "onDragStart").addListener(function(e)
            {
                newSplitter.layer.parentNode.appendChild(newSplitter.layer);
            }
        );
        
        
        // Add in that index
        newSplitter.index = this.splitterBars.length;
        // append to our splitterBar array...
        this.splitterBars.append(newSplitter);
    }
    
    // append ALL splitters, calling the move handler for each
    for (var i = 0; i < this.splitterBars.length; i++)
    {
        var bar = this.splitterBars[i];
        
        this.layer.appendChild(bar.layer);
        // Set the position, minX etc...
        
        switch (this.splitterType)
        {
            case this.splitterTypes.Vertical:
                bar.setPosition((this.width / this.frames.length - bar.width / 2) * (i+1), 0);
                bar.dragController.minY = bar.dragController.maxY = 0;
                
                break;
            case this.splitterTypes.Horizontal:
                bar.setPosition(0, (this.height / this.frames.length - bar.height / 2) * (i+1));
                bar.dragController.minX = bar.dragController.maxX = 0;
                
                break;
            default:
                break;
        }
        // Call the move handler to set up constraints
        this.onSplitterMoveHandler({index: i, x: bar.x, y: bar.y});
    }
}




//-----------------------------------------------------------------------------
ajax.components.Splitter.toString = function()
{
    return "ajax.components.Splitter";
}

//-----------------------------------------------------------------------------
ajax.components.Splitter.cast = function(obj)
{///<returns type="ajax.components.Splitter"/>
    return obj;
}

//-----------------------------------------------------------------------------
// Statics
ajax.components.Splitter.getSplitterTypes = function()
{
    return new ajax.components.Splitter.SplitterType();
}

//-----------------------------------------------------------------------------
ajax.components.Splitter.SplitterType = function(){};
ajax.components.Splitter.SplitterType.prototype = 
{
    Vertical: 0,
    Horizontal: 1
};
//-----------------------------------------------------------------------------
ajax.components.Splitter.SplitterType.cast = function(obj)
{///<returns type="ajax.components.Splitter.SplitterType"/>
    return obj;
}